//
//  RandomGenerator.cpp
//  sad
//
//  Created by Christopher Kemsley on 4/8/12.
//  Copyright (c) 2012 iAppolopolis. All rights reserved.
//

#include "ModuleFactory.hpp"
#include "Model.hpp"

#include "BusInterface.hpp"
#include "FiFoBuffer.hpp"

#include <stdlib.h>
#include <time.h>

#include "Log.hpp"

using namespace FiFo ;







struct RandomUnsignedGeneratorSettings : public Settings
{
	std::string		fifoName ;
	SCInterval		arrivalDelay ;
	bool			generateLinearData ;
	
	RandomUnsignedGeneratorSettings ( std::string const & name )
	:	Settings	( name )
	,	fifoName	( )
	,	arrivalDelay( 1 , kSCIntervalMicroSeconds )
	,	generateLinearData(false)
		{
		add ( "arrivalDelay" , arrivalDelay ) ;
		add ( "fifoName" , fifoName ) ;
		add ( "generateLinearData" , generateLinearData ) ;
		}
	
	virtual void validate ()
		{
		if ( fifoName.size() == 0 )
			ThrowException ( "RandomUnsignedGeneratorSettings" , "FiFo-Name has 0-length" , __FILE__,__LINE__ ) ;
		if ( arrivalDelay.to_seconds() == 0 )
			ThrowException ( "RandomUnsignedGeneratorSettings" , "Inter-frame delay is zero" , __FILE__,__LINE__ ) ;
		}
} ;







struct RandomUnsignedGenerator : public ConfiguredModel<RandomUnsignedGeneratorSettings>
{
	sc_port <WriteInterface>	mpFifo ;
	
	SystemC::UInt32				mValue ;
	
	SC_HAS_PROCESS(RandomUnsignedGenerator) ;
	
	RandomUnsignedGenerator ( ModelVariant const & identity )
	:	ConfiguredModel<RandomUnsignedGeneratorSettings> ( identity )
	,	mValue ( 0 )
		{
		Subscription < WriteInterface >	pFiFo ( mConfig.fifoName ) ;
		bindPortToInterface ( &mpFifo , pFiFo ) ;
		
		srand ( time(0) ) ;
		
		SC_THREAD ( runLoop ) ;
		}
	
	
	void	runLoop ()
		{
		while ( 1 )
			{
			wait ( mConfig.arrivalDelay ) ;
			
			SystemC::UInt32	val	=	mConfig.generateLinearData ? mValue++ : rand() & 0xFFFFFFFF ;
			
			Word r ( val ) ;
			
			Log::states("RandomUnsignedGenerator") << "Writing: " << r ;
			
			mpFifo -> write ( r ) ;
			}
		}
	
} ;



TypedModuleMaker< RandomUnsignedGenerator >	bRandomUnsignedGenerator	( "model.test.generate.unsigned" ) ;
